package org.dromara.tearoom.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.area.core.AreaHierarchy;
import org.dromara.common.area.core.utils.AreaUtils;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.PositionUtil;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.tearoom.domain.TerRegionalInfo;
import org.dromara.tearoom.domain.bo.TerRegionalInfoBo;
import org.dromara.tearoom.domain.bo.TerRoomDetailsWxBo;
import org.dromara.common.core.domain.vo.CityVo;
import org.dromara.tearoom.domain.vo.TerRegionalInfoVo;
import org.dromara.tearoom.mapper.TerRegionalInfoMapper;
import org.dromara.tearoom.service.ITerRegionalInfoService;
import org.dromara.tearoom.service.ITerRoomDetailsService;
import org.dromara.common.core.utils.PinYinUtil;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * 区域信息Service业务层处理
 *
 * @author xch
 * @date 2025-04-09
 */
@RequiredArgsConstructor
@Service
public class TerRegionalInfoServiceImpl implements ITerRegionalInfoService {

    private final TerRegionalInfoMapper baseMapper;
    private final ITerRoomDetailsService terRoomDetailsService;

    /**
     * 查询区域信息
     *
     * @param id 主键
     * @return 区域信息
     */
    @Override
    public TerRegionalInfoVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询区域信息列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 区域信息分页列表
     */
    @Override
    public TableDataInfo<TerRegionalInfoVo> queryPageList(TerRegionalInfoBo bo, PageQuery pageQuery) {
        Page<TerRegionalInfoVo> result = baseMapper.selectVoPageList(pageQuery.build(),bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的区域信息列表
     *
     * @param bo 查询条件
     * @return 区域信息列表
     */
    @Override
    public List<TerRegionalInfoVo> queryList(TerRegionalInfoBo bo) {
        LambdaQueryWrapper<TerRegionalInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<TerRegionalInfoVo> queryAppList(TerRegionalInfoBo bo){
        LambdaQueryWrapper<TerRegionalInfo> lqw = buildQueryWrapper(bo);
        List<TerRegionalInfoVo> regionalInfoVoList= baseMapper.selectVoList(lqw);
        regionalInfoVoList.stream().forEach(regionalInfoVo -> {
            TerRoomDetailsWxBo roomDetailsWxBo=new TerRoomDetailsWxBo();
            roomDetailsWxBo.setGroupId(regionalInfoVo.getId());
            regionalInfoVo.setRoomList(terRoomDetailsService.queryList(roomDetailsWxBo));
        });
        return regionalInfoVoList;
    }

    /**
     * 查询符合条件的门店分页信息列表
     *
     * @param bo 查询条件
     * @return 区域信息列表
     */
    @Override
    public TableDataInfo<TerRegionalInfoVo> queryAppPageList(TerRegionalInfoBo bo,PageQuery pageQuery) {
        Page<TerRegionalInfoVo> result = baseMapper.selectVoPageList(pageQuery.build(),bo);
        result.getRecords().stream().forEach(item->{
            if(ObjectUtil.isAllNotEmpty(bo.getLongitude(),bo.getLatitude(),item.getLongitude(),item.getLatitude())){
                item.setDistance(PositionUtil.getDistance(bo.getLongitude(),bo.getLatitude(),item.getLongitude(),item.getLatitude()));
            }
        });
        // 按距离升序排序，null 值放在最后
        result.getRecords().sort(Comparator.comparingDouble(
            (TerRegionalInfoVo item) -> item.getDistance() != null ? item.getDistance() : Double.MAX_VALUE
        ));
        return TableDataInfo.build(result);
    }


    private LambdaQueryWrapper<TerRegionalInfo> buildQueryWrapper(TerRegionalInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TerRegionalInfo> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(TerRegionalInfo::getOrderNum);
        lqw.eq(ObjectUtil.isNotEmpty(bo.getDistrictId()), TerRegionalInfo::getDistrictId, bo.getDistrictId());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getCityId()), TerRegionalInfo::getCityId, bo.getCityId());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getProvinceId()), TerRegionalInfo::getProvinceId, bo.getProvinceId());
        lqw.like(StringUtils.isNotBlank(bo.getAddress()), TerRegionalInfo::getAddress, bo.getAddress());
        lqw.like(StringUtils.isNotBlank(bo.getDistrictName()), TerRegionalInfo::getDistrictName, bo.getDistrictName());
        lqw.like(StringUtils.isNotBlank(bo.getCityName()), TerRegionalInfo::getCityName, bo.getCityName());
        lqw.like(StringUtils.isNotBlank(bo.getProvinceName()), TerRegionalInfo::getProvinceName, bo.getProvinceName());
        lqw.like(StringUtils.isNotBlank(bo.getGroupName()), TerRegionalInfo::getGroupName, bo.getGroupName());
        lqw.like(StringUtils.isNotBlank(bo.getPhone()), TerRegionalInfo::getPhone, bo.getPhone());
        return lqw;
    }

    /**
     * 新增区域信息
     *
     * @param bo 区域信息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TerRegionalInfoBo bo) {
        bo.setDelFlag("0");
        TerRegionalInfo add = BeanUtil.toBean(bo, TerRegionalInfo.class);
        validEntityBeforeSave(add);
        setAreaInfo(add,bo.getArea());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改区域信息
     *
     * @param bo 区域信息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TerRegionalInfoBo bo) {
        TerRegionalInfo update = BeanUtil.toBean(bo, TerRegionalInfo.class);
        validEntityBeforeSave(update);
        setAreaInfo(update,bo.getArea());
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TerRegionalInfo entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除区域信息信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            // 检查所有记录是否都处于已删除状态
            List<TerRegionalInfoVo> records = baseMapper.selectVoList(new LambdaQueryWrapper<TerRegionalInfo>()
                .select(TerRegionalInfo::getId, TerRegionalInfo::getDelFlag)
                .in(TerRegionalInfo::getId, ids));
            if (records.size() != ids.size()) {
                throw new ServiceException("部分记录不存在或已被删除");
            }
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 校验并批量恢复区域信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean recoverWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            throw new ServiceException("恢复ID不能为空");
        }
        // 有效性校验
        if (Boolean.TRUE.equals(isValid)) {
            List<TerRegionalInfo> records = baseMapper.selectDelFlagsByIds(ids);
            // 检查记录数是否匹配
            if (records.size() != ids.size()) {
                throw new ServiceException("部分记录不存在或已被删除");
            }
            // 检查是否全部为已删除状态
            boolean hasNotDeleted = records.stream()
                .anyMatch(item -> !"1".equals(item.getDelFlag()));
            if (hasNotDeleted) {
                throw new ServiceException("存在非删除状态记录，无法恢复");
            }
        }
        // 执行恢复操作
        int updateCount = baseMapper.recoverByIds(ids, LoginHelper.getUserId());
        if (updateCount == 0) {
            throw new ServiceException("恢复失败，请检查记录状态");
        }
        return updateCount>0;
    }

    /**
     * 校验并批量永久区域信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean foreverDeleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            throw new ServiceException("恢复ID不能为空");
        }
        // 有效性校验
        if (Boolean.TRUE.equals(isValid)) {
            List<TerRegionalInfo> records = baseMapper.selectDelFlagsByIds(ids);
            // 检查记录数是否匹配
            if (records.size() != ids.size()) {
                throw new ServiceException("部分记录不存在或已被删除");
            }
            // 检查是否全部为已删除状态
            boolean hasNotDeleted = records.stream()
                .anyMatch(item -> !"1".equals(item.getDelFlag()));
            if (hasNotDeleted) {
                throw new ServiceException("存在非删除状态记录，无法永久删除");
            }
        }
        // 执行恢复操作
        int deleteCount = baseMapper.foreverDeleteByIds(ids);
        if (deleteCount == 0) {
            throw new ServiceException("永久删除失败，请检查记录状态");
        }
        return deleteCount>0;
    }

    /**
     * 查询已开通城市
     *
     * @return
     */
    @Override
    public List<CityVo> getOpenCity() {
        List<CityVo> cityVoList=baseMapper.selectOpenedCities();
        if(CollUtil.isNotEmpty(cityVoList)){
            cityVoList.stream().forEach(item->{
               item.setPinyinInitials(PinYinUtil.getCityPinyinInitials(item.getName()));
            });
        }
        return cityVoList;
    }


    @Override
    public List<TerRegionalInfoVo> queryGroup(){
        LambdaQueryWrapper<TerRegionalInfo> lqw = Wrappers.lambdaQuery();
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 设置区域信息
     * @param entity 目标实体
     * @param areaIds 区域ID列表
     */
    private void setAreaInfo(TerRegionalInfo entity, List<Integer> areaIds) {
        if (CollUtil.isNotEmpty(areaIds)) {
            AreaHierarchy areaHierarchy = AreaUtils.getAreaHierarchy(areaIds);
            if (ObjectUtil.isNotEmpty(areaHierarchy)) {
                // 设置区域层级信息
                entity.setDistrictId(areaHierarchy.getDistrictId());
                entity.setDistrictName(areaHierarchy.getDistrictName());
                entity.setCityId(areaHierarchy.getCityId());
                entity.setCityName(areaHierarchy.getCityName());
                entity.setProvinceId(areaHierarchy.getProvinceId());
                entity.setProvinceName(areaHierarchy.getProvinceName());
            }
        }
    }
}
